#include "trainstaticgesturedialog.h"
#include "ui_trainstaticgesturedialog.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QImage>
#include <QFile>
#include <QTextStream>
#include <QMap>

#include <cv.h>
#include <highgui.h>

#include "handgestureexception.h"

using namespace cv;
using namespace mlgesture;


TrainStaticGestureDialog::TrainStaticGestureDialog(QWidget *parent) :
    QDialog(parent),
    ui_(new Ui::TrainStaticGestureDialog)
{
    ui_->setupUi(this);
	connect(ui_->selectFilesButton, SIGNAL(clicked()), this, SLOT(selectFiles()));
	connect(ui_->resFileButton, SIGNAL(clicked()), this, SLOT(selectResultFile()));
	connect(ui_->labelFileButton, SIGNAL(clicked()), this, SLOT(selectLabelFile()));
}

TrainStaticGestureDialog::~TrainStaticGestureDialog()
{
    delete ui_;
}

void TrainStaticGestureDialog::selectFiles() {
	files_ = QFileDialog::getOpenFileNames(this, tr("Wybierz pliki z gestami"), QDir::currentPath(), tr("*.bmp"));
	ui_->selectFilesLabel->setText(tr("Wybrano ") + QString::number(files_.size()) + tr(" plików"));
}

void TrainStaticGestureDialog::selectResultFile() {
	resultFile_ = QFileDialog::getSaveFileName(this, tr("Wybierz plik na dane wynikowe"), QDir::currentPath(), QString(), 0,
											  QFileDialog::DontConfirmOverwrite);
	ui_->resFileEdit->setText(resultFile_.trimmed());
}

void TrainStaticGestureDialog::selectLabelFile() {
	labelsFile_ = QFileDialog::getSaveFileName(this, tr("Wybierz plik na etykiety"), QDir::currentPath(), QString(), 0,
											  QFileDialog::DontConfirmOverwrite);
	ui_->labelFileEdit->setText(labelsFile_.trimmed());
}

void TrainStaticGestureDialog::accept() {
	if (files_.size() == 0) {
		QMessageBox::warning(this, tr("Brak plików"), tr("Nie wybrano żadnych plików do przetwarzania"));
	}
	else if (resultFile_.trimmed().isEmpty()) {
		QMessageBox::warning(this, tr("Brak pliku wyników"), tr("Nie wybrano pliku wynikowego"));
	}
	else if (labelsFile_.trimmed().isEmpty()) {
		QMessageBox::warning(this, tr("Brak pliku etykiet"), tr("Nie wybrano pliku etykiet"));
	}
	else if (ui_->categoryEdit->text().trimmed().isEmpty()) {
		QMessageBox::warning(this, tr("Brak kategorii"), tr("Nie wybrano nazwy klasy"));
	}
	else {
		QFile file(resultFile_.trimmed());
		if (ui_->clearBox->isChecked()){
			file.open(QIODevice::WriteOnly | QIODevice::Truncate);
		}
		else {
			file.open(QIODevice::WriteOnly | QIODevice::Append);
		}
		if (!file.isOpen()) {
			throw HandGestureException(("Cannot open " + resultFile_ + " file").toStdString());
		}
		QTextStream out(&file);

		QMap<QString, int> labelMap;
		int lastLabelId = 0;
		if (!ui_->clearBox->isChecked()) {
			QFile labels(labelsFile_.trimmed());
			labels.open(QIODevice::ReadOnly);
			if (!labels.isOpen()) {
				throw HandGestureException(("Cannot open " + labelsFile_ + " file").toStdString());
			}
			QTextStream outLabels(&labels);
			QString line = outLabels.readLine();
			while (!line.isNull()) {
				QStringList list = line.split(" ");
				if (list.size() != 2)
					throw HandGestureException("Labels file has bad structure");
				bool ok;
				int tmpId = list[1].toInt(&ok);
				if (tmpId > lastLabelId) {
					lastLabelId = tmpId;
				}
				if (!ok)
					throw HandGestureException("Labels file has bad structure");
				labelMap[list[0]] = tmpId;
				line = outLabels.readLine();
			}
			labels.close();
		}
		if (!labelMap.contains(ui_->categoryEdit->text().trimmed()))
		{
			labelMap[ui_->categoryEdit->text().trimmed()] = ++lastLabelId;
			QFile labels(labelsFile_.trimmed());
			if (ui_->clearBox->isChecked()){
				labels.open(QIODevice::WriteOnly | QIODevice::Truncate);
			}
			else {
				labels.open(QIODevice::WriteOnly | QIODevice::Append);
			}
			if (!labels.isOpen()) {
				throw HandGestureException(("Cannot open " + labelsFile_ + " file").toStdString());
			}
			QTextStream outLabels(&labels);
			outLabels << ui_->categoryEdit->text().trimmed() << " " << lastLabelId << endl;
			labels.close();
		}

		for (int i=0; i<files_.size(); i++) {
			QImage qimg(files_[i]);
			if (qimg.isNull())
				continue;
			Mat img_tmp = Mat(qimg.height(), qimg.width(), CV_8UC4, (uchar*)qimg.bits(), qimg.bytesPerLine());
			Mat img = Mat(img_tmp.rows, img_tmp.cols, CV_8UC3 );
			int from_to[] = { 0,0,  1,1,  2,2 };
			mixChannels( &img_tmp, 1, &img, 1, from_to, 3 );
			Mat gray_img;
			cvtColor(img, gray_img, CV_BGR2GRAY);

			out << labelMap[ui_->categoryEdit->text().trimmed()];
			Moments m = moments(gray_img, true);
			double hu[7];
			HuMoments(m, hu);
			for (int j=0; j<7; j++) {
				out << " " << j+1 << ":" << hu[j];
			}
			out << endl;
		}
		file.close();
		QDialog::accept();
	}
}
